package br.ceut.especializacao.poo.exemplares;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import br.ceut.especializacao.poo.livros.Livro;
import br.ceut.especializacao.poo.livros.LivroNaoEncontradoException;
import br.ceut.especializacao.poo.livros.RepositorioLivros;
import br.ceut.especializacao.poo.livros.RepositorioLivrosArray;
import br.ceut.especializacao.poo.livros.RepositorioLivrosBDR;
import br.ceut.especializacao.poo.util.PersistenceMechanismException;
import br.ceut.especializacao.poo.util.PersistenceMechanismRDBMS;
import br.ceut.especializacao.poo.util.RepositorioException;

public class RepositorioExemplaresBDR implements RepositorioExemplares {

	private static RepositorioExemplaresBDR instance;
	private PersistenceMechanismRDBMS pm;

	private RepositorioExemplaresBDR() {
		try {
			pm = PersistenceMechanismRDBMS.getInstance();
			pm.connect();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public synchronized static RepositorioExemplaresBDR getInstance() {
		if (instance == null) {
			instance = new RepositorioExemplaresBDR();
		}
		return instance;
	}

	public void inserir(Exemplar exemplar) throws RepositorioException {
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			statement.executeQuery("INSERT INTO EXEMPLAR VALUES ('" + exemplar.getLivro().getIsbn() + "')");
		} catch (PersistenceMechanismException ex) {
			throw new RepositorioException(ex);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
	}

	public void remover(int idExemplar) throws ExemplarNaoEncontradoException,
			RepositorioException {
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			int i = statement.executeUpdate("DELETE FROM EXEMPLAR WHERE idExemplar='" + idExemplar + "'");
			if (i == 0) {
				throw new ExemplarNaoEncontradoException(idExemplar);
			}
		} catch (PersistenceMechanismException e) {
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
	}

	public Exemplar procurar(int idExemplar) throws ExemplarNaoEncontradoException,
			RepositorioException {
		Exemplar exemplar = null;
		Livro livro = null;
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			ResultSet resultset = statement.executeQuery("SELECT * FROM EXEMPLAR WHERE idExemplar = '" + idExemplar + "'");
			if (resultset.next()) {
				try {
					livro = RepositorioLivrosBDR.getInstance().procurar(resultset.getString("isbn"));
				} catch (LivroNaoEncontradoException e) {
					e.printStackTrace();
				} 
				exemplar = new Exemplar(resultset.getInt("idAutor"), livro);
			} else {
				throw new ExemplarNaoEncontradoException(idExemplar);
			}
			resultset.close();
		} catch (PersistenceMechanismException ex) {
			throw new RepositorioException(ex);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
		return exemplar;
	}

	public void atualizar(Exemplar exemplar) throws ExemplarNaoEncontradoException,
			RepositorioException {
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			statement.executeUpdate("UPDATE EXEMPLAR SET idLivro = '" + exemplar.getLivro().getIsbn() + "' WHERE nome = '" + exemplar.getIdExemplar() + "'");

		} catch (PersistenceMechanismException ex) {
			throw new RepositorioException(ex);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
	}

	public boolean existe(int idExemplar) throws RepositorioException {
		boolean resposta = false;
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			ResultSet resultset = statement.executeQuery("SELECT * FROM EXEMPLAR WHERE idExemplar = " + idExemplar + "");
			resposta = resultset.next();
			resultset.close();
		} catch (PersistenceMechanismException e) {
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
		return resposta;
	}

	public IteratorExemplares getIterator() throws RepositorioException {
		return this.getIterator();
	}

	@Override
	public List<Exemplar> getExemplares() throws RepositorioException {
		RepositorioExemplares resposta = new RepositorioExemplaresArray(20);
		try {
			Statement statement = (Statement) pm.getCommunicationChannel();
			ResultSet resultset = statement.executeQuery("SELECT exemplar.idExemplar, livro.isbn, livro.titulo, livro.editora FROM EXEMPLAR inner join livro on exemplar.idLivro = livro.idLivro order by idExemplar desc");
			Livro livro = null;
			Exemplar exemplar = null;
			while (resultset.next()) {
				livro = new Livro(resultset.getString("isbn"), resultset.getString("titulo"), resultset.getString("editora"));
				exemplar = new Exemplar(resultset.getInt("idExemplar"), livro);
				
				resposta.inserir(exemplar);
			}
			resultset.close();
		} catch (PersistenceMechanismException e) {
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
		return resposta.getExemplares();
	}

}